home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-05 | 17.0 KB | 298 lines | [TEXT/PJMM] |
- {****************************************************}
- {}
- { CFSAircraftPane.p }
- {}
- { Pane methods for the aircraft pane. }
- {}
- { Copyright © 1995, Patrick Hew. All rights reserved. }
- {}
- {****************************************************}
-
-
- unit CFSAircraftPane;
-
- interface
-
- uses
- TCL, FSIntf;
-
- implementation
-
-
- { PerspectiveProjection }
- {}
- { Returns: The projection of aPoint onto the plane with origin aPlaneOrigin and }
- { axes aAxis1 and aAxis2, where the eye point is at aEyeDist from aPlaneOrigin }
- { in the direction aAxis1 x aAxis2. That is, we look from aEyeDist along }
- { aAxis1 x aAxis2 through aPlaneOrigin. }
- { Reference: Taken from Section 16.2 of: }
- { "Computer Graphics - An Introduction to the Mathematics and Geometry" }
- { by M E Mortenson, published by Industrial Press, NY, 1989. }
- { Actually, I think that the z coordinate after projection is a bit bogus, but as it }
- { is probably never used, it is unlikely to really matter. }
-
- function PerspectiveProjection (aPoint, aCentreOfProjection, aAxis1, aAxis2: V3Type; aEyeDist: Real): V3Type;
-
- var
- u1, u2, u3: V3Type;
- pointOffset: V3Type;
- depthScale: Real;
-
- begin { PerspectiveProjection }
- u1 := V3Normalized(aAxis1);
- u2 := V3Normalized(aAxis2);
- u3 := V3CrossProduct(u1, u2);
-
- pointOffset := V3Diff(aPoint, aCentreOfProjection);
- depthScale := V3DotProduct(pointOffset, u3) - aEyeDist;
-
- PerspectiveProjection := V3Scale(-aEyeDist / depthScale, V3FromScalars(V3DotProduct(pointOffset, u1), V3DotProduct(pointOffset, u2), 1));
- end; { PerspectiveProjection }
-
-
- { IFSAircraftPane }
- {}
- { Post: The aircraft pane has been initialized. }
-
- procedure CFSAircraftPane.IFSAircraftPane (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth, aHeight, aHEncl, aVEncl: integer; aHSizing, aVSizing: SizingOption);
-
- begin { IFSAircraftPane }
- IPane(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
-
- fuselageTopLeft[1] := V3FromScalars(-200, 40, 40);
- fuselageTopLeft[2] := V3FromScalars(200, 40, 40);
- fuselageTopLeft[3] := V3FromScalars(220, 60, 0);
- fuselageTopLeft[4] := V3FromScalars(-200, 60, 0);
-
- fuselageTopRight[1] := V3FromScalars(-200, -40, 40);
- fuselageTopRight[2] := V3FromScalars(-200, -60, 0);
- fuselageTopRight[3] := V3FromScalars(220, -60, 0);
- fuselageTopRight[4] := V3FromScalars(200, -40, 40);
-
- fuselageTopCentre[1] := fuselageTopLeft[1];
- fuselageTopCentre[2] := fuselageTopRight[1];
- fuselageTopCentre[3] := fuselageTopRight[4];
- fuselageTopCentre[4] := fuselageTopLeft[2];
-
- noseCentre[1] := V3FromScalars(700, 0, 0);
- noseCentre[2] := fuselageTopCentre[4];
- noseCentre[3] := fuselageTopCentre[3];
-
- noseLeft[1] := fuselageTopLeft[2];
- noseLeft[2] := noseCentre[1];
- noseLeft[3] := fuselageTopLeft[3];
-
- noseRight[1] := fuselageTopRight[3];
- noseRight[2] := noseCentre[1];
- noseRight[3] := fuselageTopRight[4];
-
- cockpitFront[1] := V3FromScalars(360, 20, 30);
- cockpitFront[2] := V3FromScalars(280, 20, 80);
- cockpitFront[3] := V3FromScalars(280, -20, 80);
- cockpitFront[4] := V3FromScalars(360, -20, 30);
-
- cockpitBack[1] := cockpitFront[2];
- cockpitBack[2] := V3FromScalars(200, 20, 40);
- cockpitBack[3] := V3FromScalars(200, -20, 40);
- cockpitBack[4] := cockpitFront[3];
-
- fuselageBottomLeft[1] := V3FromScalars(-200, 40, -40);
- fuselageBottomLeft[2] := fuselageTopLeft[4];
- fuselageBottomLeft[3] := V3FromScalars(160, 60, 0);
- fuselageBottomLeft[4] := V3FromScalars(160, 40, -40);
-
- fuselageBottomRight[1] := V3FromScalars(-200, -40, -40);
- fuselageBottomRight[2] := V3FromScalars(160, -40, -40);
- fuselageBottomRight[3] := V3FromScalars(160, -60, 0);
- fuselageBottomRight[4] := fuselageTopRight[2];
-
- fuselageBottomCentre[1] := fuselageBottomLeft[1];
- fuselageBottomCentre[2] := fuselageBottomLeft[4];
- fuselageBottomCentre[3] := fuselageBottomRight[2];
- fuselageBottomCentre[4] := fuselageBottomRight[1];
-
- intake[1] := fuselageBottomLeft[3];
- intake[2] := fuselageBottomRight[3];
-
- leftWing[1] := V3FromScalars(180, 60, 0);
- leftWing[2] := V3FromScalars(0, 320, 0);
- leftWing[3] := V3FromScalars(-40, 320, 0);
- leftWing[4] := V3FromScalars(-40, 60, 0);
-
- rightWing[1] := V3FromScalars(180, -60, 0);
- rightWing[2] := V3FromScalars(-40, -60, 0);
- rightWing[3] := V3FromScalars(-40, -320, 0);
- rightWing[4] := V3FromScalars(0, -320, 0);
-
- leftTail[1] := V3FromScalars(-100, 60, 0);
- leftTail[2] := V3FromScalars(-160, 160, 0);
- leftTail[3] := V3FromScalars(-180, 160, 0);
- leftTail[4] := V3FromScalars(-180, 60, 0);
-
- rightTail[1] := V3FromScalars(-100, -60, 0);
- rightTail[2] := V3FromScalars(-180, -60, 0);
- rightTail[3] := V3FromScalars(-180, -160, 0);
- rightTail[4] := V3FromScalars(-160, -160, 0);
-
- tailFin[1] := V3FromScalars(-180, 0, 40);
- tailFin[2] := V3FromScalars(-180, 0, 200);
- tailFin[3] := V3FromScalars(-140, 0, 200);
- tailFin[4] := V3FromScalars(0, 0, 40);
- end; { IFSAircraftPane }
-
-
- { UpdateAircraft }
- {}
- { Post: The bank and AOA have been updated. This effects the local }
- { coordinate change from absolute to aircraft, although this }
- { implementation does not use this fact. }
- { Note: We should really do this by sending a message to the aircraft }
- { itself, rather than the pane, but this is a hack. }
-
- procedure CFSAircraftPane.UpdateAircraft (aBank, aAOA: Real);
-
- begin { UpdateAircraft }
- itsBank := aBank;
- itsAOA := aAOA;
-
- { Always refresh. }
- Refresh;
- end; { UpdateAircraft }
-
-
- { Draw }
- {}
- { Post: The aircraft has been drawn. We draw a wireframe. }
- { For some reason, backface elimination is unreliable with }
- { perspective projection. }
-
- const
- kCentreh = kAircraftPaneLenh div 2;
- kCentrev = kAircraftPaneLenv div 2;
-
- procedure CFSAircraftPane.Draw (var area: Rect);
-
- var
- theBankMatrix, theAOAMatrix: M3Type;
-
- { We will need to store up to 6 projected points at once. }
- { Kludge! Kludge! Kludge! :) }
- theArrayIndex: Integer;
- theProjectionStore: array[1..6] of Point;
- theProjection: V3Type;
-
- theCentreOfProjection, theAxis1, theAxis2: V3Type;
- theEyeDist: Real;
-
-
- begin { Draw }
- { We pitch the aircraft around the y axis and roll around the x. }
- { Note that this will give the same result for pitch-roll and roll-pitch, }
- { though of course in real life this is not the case. }
-
- { The camera in absolute space is fixed, and is as follows. }
- theAxis1 := V3FromScalars(0, -1, 0);
- theAxis2 := V3FromScalars(1, 0, 4);
- theCentreOfProjection := V3FromScalars(-400, 0, 100);
- theEyeDist := 200;
-
- { Note that for the aircraft, positive bank is a positive rotation about }
- { the x axis, and positive pitch is a negative rotation about the y axis. }
- { Further note that we map the aircraft by this amount, so the }
- { transition matrices are the inverse. }
- theBankMatrix := RotX(-itsBank);
- theAOAMatrix := RotY(itsAOA);
-
- { Left of nose. }
- for theArrayIndex := 1 to 3 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, noseLeft[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[3].h, theProjectionStore[3].v);
- for theArrayIndex := 1 to 3 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Centre of nose. }
- for theArrayIndex := 1 to 3 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, noseCentre[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[3].h, theProjectionStore[3].v);
- for theArrayIndex := 1 to 3 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Right of nose. }
- for theArrayIndex := 1 to 3 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, noseRight[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[3].h, theProjectionStore[3].v);
- for theArrayIndex := 1 to 3 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Front of cockpit. }
- for theArrayIndex := 1 to 4 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, cockpitFront[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
- for theArrayIndex := 1 to 4 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Back of cockpit. }
- for theArrayIndex := 1 to 4 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, cockpitBack[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
- for theArrayIndex := 1 to 4 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Top left of fuselage. }
- for theArrayIndex := 1 to 4 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageTopLeft[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
- for theArrayIndex := 1 to 4 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Top centre of fuselage. }
- for theArrayIndex := 1 to 4 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageTopCentre[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
- for theArrayIndex := 1 to 4 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Top right of fuselage. }
- for theArrayIndex := 1 to 4 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageTopRight[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
- end; { for }
- MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
- for theArrayIndex := 1 to 4 do begin
- LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
- end; { for }
-
- { Bottom left of fuselage. }
- for theArrayIndex := 1 to 4 do begin
- theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageBottomLeft[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
- theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
- theProjectionStore[theArrayIndex].v := kCentrev - Tr